#include <QCoreApplication>
#include <QSerialPort>
#include <QThread>
#include <QTimer>
#include <QDateTime>
#include <QDebug>

#include "ui_ctrl/ui_controller.h"
#include "coordinator/coordinator.h"
#include "ui_ctrl/ui_screen_definitions.h"
#include "ui_ctrl/ui_widgets.h"
#include "fingerprint/fingerprint.h"
#include "setting/version.h"

#define PERIOD_SHORT					 8000		// 10 seconds
#define PERIOD_LONG						20000		// 20 seconds

UIWidgetController::UIWidgetController(UIController_Worker *ui_controller, QObject *parent)
	: QObject(parent)
{
	m_ui_controller = ui_controller;
	moveToThread(m_ui_controller->thread());

	connect(this, &UIWidgetController::set_screen, this, &UIWidgetController::scrn_init);
	connect(this, &UIWidgetController::set_screen, m_ui_controller, &UIController_Worker::set_screen);
	connect(this, &UIWidgetController::pop_screen, this, &UIWidgetController::scrn_pop);
	connect(this, &UIWidgetController::set_btn_status, m_ui_controller, &UIController_Worker::set_btn_status);
	connect(this, &UIWidgetController::set_text, m_ui_controller, &UIController_Worker::set_text);
	connect(this, &UIWidgetController::set_select, m_ui_controller, &UIController_Worker::set_select);
	connect(this, &UIWidgetController::set_enable, m_ui_controller, &UIController_Worker::set_enable);
	connect(this, &UIWidgetController::set_table_data, m_ui_controller, &UIController_Worker::set_table_data);
	connect(this, &UIWidgetController::set_visible, m_ui_controller, &UIController_Worker::set_visible);

	connect(m_ui_controller, &UIController_Worker::scrn_switched, this, &UIWidgetController::scrn_switched);
	connect(m_ui_controller, &UIController_Worker::btn_clicked, this, &UIWidgetController::btn_clicked);
	connect(m_ui_controller, &UIController_Worker::txt_changed, this, &UIWidgetController::txt_changed);
	connect(m_ui_controller, &UIController_Worker::sel_changed, this, &UIWidgetController::sel_changed);
	connect(m_ui_controller, &UIController_Worker::tab_sel_changed, this, &UIWidgetController::tab_sel_changed);

	scrn_widget_init();
	m_admin_status = false;

	QTimer::singleShot(200, this, &UIWidgetController::start);
}

UIWidgetController::~UIWidgetController()
{
	delete m_second_timer;
}

void UIWidgetController::start()
{
	m_second_timer = new QTimer();
	m_second_timer->start(1000);
	connect(m_second_timer, &QTimer::timeout, this, &UIWidgetController::update_time);
	m_prompt_timer = new QTimer();
	m_prompt_timer->setSingleShot(true);
	connect(m_prompt_timer, &QTimer::timeout, this, &UIWidgetController::hide_prompt);

	emit set_screen(SCRN_main);
}

void UIWidgetController::update_time()
{
	emit set_text((m_curr_scrn_id << 16) + SCRN_generic_TXT_time, QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
}

void UIWidgetController::unlock_scrn()
{
	m_btn_locked = false;
}

void UIWidgetController::hide_prompt()
{
	emit set_visible((m_curr_scrn_id << 16) | SCRN_generic_TXT_prompt, false);
}

void UIWidgetController::scrn_switched(uint32_t scrn_id)
{
	m_curr_scrn_id = scrn_id;
}

void UIWidgetController::btn_clicked(uint32_t widget_id)
{
	QDate start_date, stop_date;
	QString rec_idx_s;

	if (m_btn_locked) {
		qInfo() << "[UI]Ignore Button Click" << QString("(%1, %2)").arg(widget_id >> 16, 4).arg(widget_id & 0xffff, 4);
		return;
	}

	switch (widget_id >> 16) {
	case SCRN_main:
		switch ((widget_id & 0xffff)) {
		case WIDGET_BTN(main, password_modify):
			emit set_enable((SCRN_password_modify << 16) | WIDGET_TXT(password_modify, username), true);
			emit set_screen(SCRN_password_modify);
			break;
		case WIDGET_BTN(main, login):
			emit user_login(
					fetch_widget_value(SCRN_main, WIDGET_TXT(main, username)),
					fetch_widget_value(SCRN_main, WIDGET_TXT(main, password)));
			break;
		}
		break;
	case SCRN_password_modify:
		switch ((widget_id & 0xffff)) {
		case WIDGET_BTN(password_modify, confirm):
			emit user_modify_password(
					fetch_widget_value(SCRN_password_modify, WIDGET_TXT(password_modify, username)),
					fetch_widget_value(SCRN_password_modify, WIDGET_TXT(password_modify, old_password)),
					fetch_widget_value(SCRN_password_modify, WIDGET_TXT(password_modify, new_password)));
			break;
		case WIDGET_BTN(password_modify, cancel):
			emit pop_screen();
		}
		break;
	case SCRN_intelligent_mode:
		if (Coordinator::coordinator()->nc_in_operation())
			break;
		switch ((widget_id & 0xffff)) {
		case WIDGET_BTN(intelligent_mode, cancel):
			emit pop_screen();
			emit enter_init_mode();
			break;
		case WIDGET_BTN(intelligent_mode, continue):
			emit countinue_count();
			break;
		}
		break;
	case SCRN_mixed_mode:
		if (Coordinator::coordinator()->nc_in_operation())
			break;
		switch ((widget_id & 0xffff)) {
		case WIDGET_BTN(mixed_mode, cancel):
			emit pop_screen();
			emit enter_init_mode();
			break;
		case WIDGET_BTN(mixed_mode, continue):
			emit countinue_count();
			break;
		}
		break;
	case SCRN_count_mode:
		if (Coordinator::coordinator()->nc_in_operation())
			break;
		switch ((widget_id & 0xffff)) {
		case WIDGET_BTN(count_mode, cancel):
			emit pop_screen();
			emit enter_init_mode();
			break;
		case WIDGET_BTN(count_mode, continue):
			emit countinue_count();
			break;
		}
		break;
	case SCRN_deposit_category8:
		switch ((widget_id & 0xffff)) {
		case WIDGET_BTN(deposit_category8, inquiry):
			emit set_screen(SCRN_deposit_inquiry);
			break;
		case WIDGET_BTN(deposit_category8, return):
			emit pop_screen();
			emit enter_init_mode();
			break;
		case WIDGET_BTN(deposit_category8, category1):
			m_trans_type = Coordinator::coordinator()->category_code(0);
			emit set_screen(SCRN_deposit_class);
			break;
		case WIDGET_BTN(deposit_category8, category2):
			m_trans_type = Coordinator::coordinator()->category_code(1);
			emit set_screen(SCRN_deposit_class);
			break;
		case WIDGET_BTN(deposit_category8, category3):
			m_trans_type = Coordinator::coordinator()->category_code(2);
			emit set_screen(SCRN_deposit_class);
			break;
		case WIDGET_BTN(deposit_category8, category4):
			m_trans_type = Coordinator::coordinator()->category_code(3);
			emit set_screen(SCRN_deposit_class);
			break;
		case WIDGET_BTN(deposit_category8, category5):
			m_trans_type = Coordinator::coordinator()->category_code(4);
			emit set_screen(SCRN_deposit_class);
			break;
		case WIDGET_BTN(deposit_category8, category6):
			m_trans_type = Coordinator::coordinator()->category_code(5);
			emit set_screen(SCRN_deposit_class);
			break;
		case WIDGET_BTN(deposit_category8, category7):
			m_trans_type = Coordinator::coordinator()->category_code(6);
			emit set_screen(SCRN_deposit_class);
			break;
		case WIDGET_BTN(deposit_category8, category8):
			m_trans_type = Coordinator::coordinator()->category_code(7);
			emit set_screen(SCRN_deposit_class);
			break;
		}
		break;
	case SCRN_deposit_category4:
		switch ((widget_id & 0xffff)) {
		case WIDGET_BTN(deposit_category4, inquiry):
			emit set_screen(SCRN_deposit_inquiry);
			break;
		case WIDGET_BTN(deposit_category4, return):
			emit pop_screen();
			emit enter_init_mode();
			break;
		case WIDGET_BTN(deposit_category4, category1):
			m_trans_type = Coordinator::coordinator()->category_code(0);
			emit set_screen(SCRN_deposit_class);
			break;
		case WIDGET_BTN(deposit_category4, category2):
			m_trans_type = Coordinator::coordinator()->category_code(1);
			emit set_screen(SCRN_deposit_class);
			break;
		case WIDGET_BTN(deposit_category4, category3):
			m_trans_type = Coordinator::coordinator()->category_code(2);
			emit set_screen(SCRN_deposit_class);
			break;
		case WIDGET_BTN(deposit_category4, category4):
			m_trans_type = Coordinator::coordinator()->category_code(3);
			emit set_screen(SCRN_deposit_class);
			break;
		}
		break;
	case SCRN_deposit_category3:
		switch ((widget_id & 0xffff)) {
		case WIDGET_BTN(deposit_category3, inquiry):
			emit set_screen(SCRN_deposit_inquiry);
			break;
		case WIDGET_BTN(deposit_category3, return):
			emit pop_screen();
			emit enter_init_mode();
			break;
		case WIDGET_BTN(deposit_category3, category1):
			m_trans_type = Coordinator::coordinator()->category_code(0);
			emit set_screen(SCRN_deposit_class);
			break;
		case WIDGET_BTN(deposit_category3, category2):
			m_trans_type = Coordinator::coordinator()->category_code(1);
			emit set_screen(SCRN_deposit_class);
			break;
		case WIDGET_BTN(deposit_category3, category3):
			m_trans_type = Coordinator::coordinator()->category_code(2);
			emit set_screen(SCRN_deposit_class);
			break;
		}
		break;
	case SCRN_deposit_category2:
		switch ((widget_id & 0xffff)) {
		case WIDGET_BTN(deposit_category2, inquiry):
			emit set_screen(SCRN_deposit_inquiry);
			break;
		case WIDGET_BTN(deposit_category2, return):
			emit pop_screen();
			emit enter_init_mode();
			break;
		case WIDGET_BTN(deposit_category2, category1):
			m_trans_type = Coordinator::coordinator()->category_code(0);
			emit set_screen(SCRN_deposit_class);
			break;
		case WIDGET_BTN(deposit_category2, category2):
			m_trans_type = Coordinator::coordinator()->category_code(1);
			emit set_screen(SCRN_deposit_class);
			break;
		}
		break;
	case SCRN_deposit_class:
		switch ((widget_id & 0xffff)) {
		case WIDGET_BTN(deposit_class, inquiry):
			emit set_screen(SCRN_deposit_inquiry);
			break;
		case WIDGET_BTN(deposit_class, return):
			emit pop_screen();
			emit enter_init_mode();
			break;
		case WIDGET_BTN(deposit_class, note):
			m_trans_type = (m_trans_type / 10) * 10 + TRANS_CLASS_NOTE;
			emit enter_note_transaction_mode();
			break;
		case WIDGET_BTN(deposit_class, coin):
			m_trans_type = (m_trans_type / 10) * 10 + TRANS_CLASS_COIN;
			emit enter_coin_transaction_mode();
			break;
		}
		break;
	case SCRN_deposit_note:
		if (Coordinator::coordinator()->nc_in_operation())
			break;
		switch ((widget_id & 0xffff)) {
		case WIDGET_BTN(deposit_note, store):
			emit store_note();
			break;
		case WIDGET_BTN(deposit_note, return):
			emit finish_transaction();
			emit enter_init_mode();
			break;
		case WIDGET_BTN(deposit_note, continue):
			emit countinue_count();
			break;
		}
		break;
	case SCRN_deposit_coin:
		if (Coordinator::coordinator()->nc_in_operation())
			break;
		switch ((widget_id & 0xffff)) {
		case WIDGET_BTN(deposit_coin, print):
			emit print_coin_trans();
			break;
		case WIDGET_BTN(deposit_coin, store):
			emit store_coin();
			break;
		case WIDGET_BTN(deposit_coin, return):
			emit finish_transaction();
			emit enter_init_mode();
			break;
		}
		break;
	case SCRN_print:
		switch ((widget_id & 0xffff)) {
		case WIDGET_BTN(print, print):
            emit print_current_transaction();
		case WIDGET_BTN(print, not_print):
			emit pop_screen(SCRN_deposit_class);
			break;
		case WIDGET_BTN(print, return):
			emit pop_screen(SCRN_main);
			break;
		}
		break;
	case SCRN_deposit_inquiry:
		switch ((widget_id & 0xffff)) {
		case WIDGET_BTN(deposit_inquiry, confirm):
			{
				uint32_t start_year = fetch_widget_value(SCRN_deposit_inquiry, WIDGET_SEL(deposit_inquiry, start_year)).toUInt() + 2024;
				uint32_t start_month = fetch_widget_value(SCRN_deposit_inquiry, WIDGET_SEL(deposit_inquiry, start_month)).toUInt() + 1;
				uint32_t start_day = fetch_widget_value(SCRN_deposit_inquiry, WIDGET_SEL(deposit_inquiry, start_day)).toUInt() + 1;
				uint32_t stop_year = fetch_widget_value(SCRN_deposit_inquiry, WIDGET_SEL(deposit_inquiry, stop_year)).toUInt() + 2024;
				uint32_t stop_month = fetch_widget_value(SCRN_deposit_inquiry, WIDGET_SEL(deposit_inquiry, stop_month)).toUInt() + 1;
				uint32_t stop_day = fetch_widget_value(SCRN_deposit_inquiry, WIDGET_SEL(deposit_inquiry, stop_day)).toUInt() + 1;
				start_date = QDate(start_year, start_month, start_day);
				stop_date = QDate(stop_year, stop_month, stop_day);
			}
			emit inquiry_data(start_date, stop_date);
			break;
		case WIDGET_BTN(deposit_inquiry, return):
			emit pop_screen();
			break;
		}
		break;
	case SCRN_deposit_table:
		switch ((widget_id & 0xffff)) {
		case WIDGET_BTN(deposit_table, print):
			rec_idx_s = fetch_widget_value(SCRN_deposit_table, WIDGET_TAB(deposit_table, table));
			if (rec_idx_s != "-1")
				emit print_transaction(rec_idx_s.toUInt() + 1);
			break;
		case WIDGET_BTN(deposit_table, print_all):
			emit print_transactions();
			break;
		case WIDGET_BTN(deposit_table, return):
			emit pop_screen();
			break;
		}
		break;
	case SCRN_administry:
		m_admin_status = true;
		switch ((widget_id & 0xffff)) {
		case WIDGET_BTN(administry, user_manage):
			emit inquiry_op();
			break;
		case WIDGET_BTN(administry, machine_setting):
			emit set_screen(SCRN_machine_setting);
			break;
		case WIDGET_BTN(administry, password_modification):
			emit set_enable((SCRN_password_modify << 16) | WIDGET_TXT(password_modify, username), false);
			emit set_screen(SCRN_password_modify);
			break;
		case WIDGET_BTN(administry, clear_inquiry):
			emit set_screen(SCRN_clear_inquiry);
			break;
		case WIDGET_BTN(administry, mixed_mode):
			emit enter_mixed_mode();
			break;
		case WIDGET_BTN(administry, count_mode):
			emit enter_count_mode();
			break;
		case WIDGET_BTN(administry, intelligent_mode):
			emit enter_intelligent_mode();
			break;
		case WIDGET_BTN(administry, clear):
			emit start_clear_deposit();
			break;
		case WIDGET_BTN(administry, return):
			m_admin_status = false;
			emit pop_screen();
			break;
		}
		break;
	case SCRN_user_manage:
		switch ((widget_id & 0xffff)) {
		case WIDGET_BTN(user_manage, add):
			m_user_edit = false;
            do_edit_op("", "", "", 0);
			break;
		case WIDGET_BTN(user_manage, delete):
			rec_idx_s = fetch_widget_value(SCRN_user_manage, WIDGET_TAB(user_manage, table));
			if (rec_idx_s != "-1")
				emit delete_op(rec_idx_s.toUInt() + 1);
			break;
		case WIDGET_BTN(user_manage, edit):
			rec_idx_s = fetch_widget_value(SCRN_user_manage, WIDGET_TAB(user_manage, table));
			if (rec_idx_s != "-1") {
				m_user_edit = true;
				emit edit_op(rec_idx_s.toUInt() + 1);
			}
			break;
		case WIDGET_BTN(user_manage, return):
			emit pop_screen();
			break;
		}
		break;
	case SCRN_user_edit:
		switch ((widget_id & 0xffff)) {
		case WIDGET_BTN(user_edit, confirm):
			if (m_user_edit)
				emit update_op(
					fetch_widget_value(SCRN_user_edit, WIDGET_TXT(user_edit, user_name)),
					fetch_widget_value(SCRN_user_edit, WIDGET_TXT(user_edit, user_password)),
					fetch_widget_value(SCRN_user_edit, WIDGET_TXT(user_edit, station_id)),
                    fetch_widget_value(SCRN_user_edit, WIDGET_TXT(user_edit, finger_id)).toUInt());
			else
				emit add_op(
					fetch_widget_value(SCRN_user_edit, WIDGET_TXT(user_edit, user_name)),
					fetch_widget_value(SCRN_user_edit, WIDGET_TXT(user_edit, user_password)),
					fetch_widget_value(SCRN_user_edit, WIDGET_TXT(user_edit, station_id)));
			break;
		case WIDGET_BTN(user_edit, cancel):
			emit pop_screen();
			break;
		case WIDGET_BTN(user_edit, fingerprint):
			emit fp_enroll(fetch_widget_value(SCRN_user_edit, WIDGET_TXT(user_edit, user_name)));
			break;
		}
		break;
	case SCRN_machine_setting:
		switch ((widget_id & 0xffff)) {
		case WIDGET_BTN(machine_setting, confirm):
			emit machine_info(
					fetch_widget_value(SCRN_machine_setting, WIDGET_TXT(machine_setting, name)),
					fetch_widget_value(SCRN_machine_setting, WIDGET_TXT(machine_setting, address)),
					fetch_widget_value(SCRN_machine_setting, WIDGET_TXT(machine_setting, code)));
			emit pop_screen();
			break;
		case WIDGET_BTN(machine_setting, return):
			emit pop_screen();
			break;
		}
		break;
	case SCRN_clear_inquiry:
		switch ((widget_id & 0xffff)) {
		case WIDGET_BTN(clear_inquiry, confirm):
			{
				uint32_t start_year = fetch_widget_value(SCRN_clear_inquiry, WIDGET_SEL(clear_inquiry, start_year)).toUInt() + 2024;
				uint32_t start_month = fetch_widget_value(SCRN_clear_inquiry, WIDGET_SEL(clear_inquiry, start_month)).toUInt() + 1;
				uint32_t start_day = fetch_widget_value(SCRN_clear_inquiry, WIDGET_SEL(clear_inquiry, start_day)).toUInt() + 1;
				uint32_t stop_year = fetch_widget_value(SCRN_clear_inquiry, WIDGET_SEL(clear_inquiry, stop_year)).toUInt() + 2024;
				uint32_t stop_month = fetch_widget_value(SCRN_clear_inquiry, WIDGET_SEL(clear_inquiry, stop_month)).toUInt() + 1;
				uint32_t stop_day = fetch_widget_value(SCRN_clear_inquiry, WIDGET_SEL(clear_inquiry, stop_day)).toUInt() + 1;
				start_date = QDate(start_year, start_month, start_day);
				stop_date = QDate(stop_year, stop_month, stop_day);
			}
			emit inquiry_clr_data(start_date, stop_date);
			break;
		case WIDGET_BTN(clear_inquiry, return):
			emit pop_screen();
			break;
		}
		break;
	case SCRN_clear_table:
		switch ((widget_id & 0xffff)) {
		case WIDGET_BTN(clear_table, print):
			rec_idx_s = fetch_widget_value(SCRN_clear_table, WIDGET_TAB(clear_table, table));
			if (rec_idx_s != "-1")
				emit print_clr_transaction(rec_idx_s.toUInt() + 1);
			break;
		case WIDGET_BTN(clear_table, return):
			emit pop_screen();
			break;
		}
		break;
	case SCRN_clear_total:
		switch ((widget_id & 0xffff)) {
		case WIDGET_BTN(clear_total, confirm):
			emit set_screen(SCRN_clear_confirm);
			break;
		case WIDGET_BTN(clear_total, return):
			emit pop_screen();
			break;
		}
		break;
	case SCRN_clear_confirm:
		switch ((widget_id & 0xffff)) {
		case WIDGET_BTN(clear_confirm, confirm):
			emit clear_deposit();
			emit pop_screen(SCRN_administry);
			break;
		case WIDGET_BTN(clear_confirm, cancel):
		case WIDGET_BTN(clear_confirm, return):
			emit pop_screen(SCRN_administry);
			break;
		}
		break;
	case SCRN_store_fail:
		switch ((widget_id & 0xffff)) {
		case WIDGET_BTN(store_fail, confirm):
            emit pop_screen();
	        if (Coordinator::coordinator()->get_last_saved_trans().note_info.total_amount != 0)
                emit set_screen(SCRN_print);
	        else
                emit pop_screen(SCRN_main);
			break;
        }
		break;
	}

	m_btn_locked = true;
	QTimer::singleShot(MIN_BUTTON_CLICK_TIME, this, &UIWidgetController::unlock_scrn);
}

void UIWidgetController::txt_changed(uint32_t widget_id, QString s)
{
	Screen *screen;
	Field *field;
	uint32_t scrn_id;
	uint32_t note_count, note_amount;

	scrn_id = widget_id >> 16;
	widget_id = widget_id & 0xffff;
	for (int k = 0; k < m_screens.count(); k++) {
		screen = &m_screens[k];
		if (screen->scrn_id == scrn_id) {
			for (int k = 0; k < screen->fields.count(); k++) {
				field = &screen->fields[k];
				if (field->widget_id == widget_id && field->widget_type == WIDGET_TYPE_TEXT)
					field->widget_value = s;
			}
			switch (scrn_id) {
			case SCRN_deposit_coin:
				note_count = 0;
				note_amount = 0;
				memset(&m_note_info, 0, sizeof(m_note_info));
				for (int k = 0; k < 9; k++) {
					uint32_t count = screen->fields[k].widget_value.toUInt();
					note_count += count;
					note_amount += count * NOTE_factor(k);
					m_note_info.note_count[k] = count;
					m_note_info.note_amount[k] = count * NOTE_factor(k);
				}
				m_note_info.total_count = note_count;
				m_note_info.total_amount = note_amount;
                emit set_text((SCRN_deposit_coin << 16) + WIDGET_TXT(deposit_coin, note_total),
                				QString("%1").arg(note_amount / 100.0, 16, 'f', 2));
				emit transaction_count_info(m_note_info);
				break;
			}
			break;
		}
	}
}

void UIWidgetController::sel_changed(uint32_t widget_id, uint32_t val)
{
	Screen *screen;
	Field *field;
	uint32_t scrn_id;

	scrn_id = widget_id >> 16;
	widget_id = widget_id & 0xffff;
	for (int k = 0; k < m_screens.count(); k++) {
		screen = &m_screens[k];
		if (screen->scrn_id == scrn_id) {
			for (int k = 0; k < screen->fields.count(); k++) {
				field = &screen->fields[k];
				if (field->widget_id == widget_id && field->widget_type == WIDGET_TYPE_SELECT)
					field->widget_value = QString("%1").arg(val);
			}
			break;
		}
	}
}

void UIWidgetController::tab_sel_changed(uint32_t widget_id, uint32_t val)
{
	Screen *screen;
	Field *field;
	uint32_t scrn_id;

	scrn_id = widget_id >> 16;
	widget_id = widget_id & 0xffff;
	for (int k = 0; k < m_screens.count(); k++) {
		screen = &m_screens[k];
		if (screen->scrn_id == scrn_id) {
			for (int k = 0; k < screen->fields.count(); k++) {
				field = &screen->fields[k];
				if (field->widget_id == widget_id && field->widget_type == WIDGET_TYPE_TABLE)
					field->widget_value = QString("%1").arg(val);
			}
			break;
		}
	}
}

void UIWidgetController::set_prompt(uint32_t msg_type, uint32_t msg_id)
{
	Q_UNUSED(msg_type)

	QString message;
	uint32_t msg_widget_id = (m_curr_scrn_id << 16) | SCRN_generic_TXT_prompt;
	uint32_t msg_period = PERIOD_SHORT;

	switch (msg_id) {
	case MSG_user_authenticate_fail:
		message = tr("User name/password error!");
		break;
	case MSG_password_modify_fail:
		message = tr("User password modification failed!");
		break;
	case MSG_user_name_password_empty:
		message = tr("User name/password cannot be empty!");
		break;
	case MSG_user_add_fail:
		message = tr("Add user failed(Maybe duplicated user name)!");
		break;
	case MSG_user_update_fail:
		message = tr("Update user failed!");
		break;
	case MSG_password_same_fail:
		message = tr("The same Old/New password!");
		break;
	case MSG_user_name_exist:
		message = tr("User name already exists!");
		break;

	case MSG_nc_offline:
		message = tr("NC offline!");
		break;
	case MSG_nc_entry_empty:
		message = tr("NC no note on entry position!");
		break;
	case MSG_nc_reject_not_empty:
		message = tr("NC note in reject position!");
		break;
	case MSG_nc_collect_not_empty:
		message = tr("NC note in collection position!");
		break;
	case MSG_nc_entry_not_empty:
		message = tr("NC note on entry position!");
		break;
	case MSG_nc_collect_empty:
		message = tr("NC no note in collection position!");
		break;
	case MSG_nc_collect_full:
		message = tr("NC full in collection position!");
		break;

	case MSG_waiting_bag_door_open:
		message = tr("Waiting for bag-door opened...");
		break;
	case MSG_nc_store_started:
		msg_period = PERIOD_LONG;
		message = tr("NC storing started...");
		break;
	case MSG_nc_store_success:
		msg_period = PERIOD_SHORT;
		message = "";
		break;
	case MSG_nc_store_failed:
		message = tr("NC storing failed!");
		break;
	case MSG_nc_store_timeout:
		message = tr("NC storing timeout!");
		break;

	case MSG_nc_amount_limit:
		message = tr("NC Amount Limit reached!");
		break;

	case MSG_bag_sensor_fail:
		message = tr("Bag sensor fail!");
		break;
	case MSG_bag_door_opened:
		message = tr("Bag door opened!");
		break;
	case MSG_case_door_opened:
		message = tr("Case door opened!");
		break;

	default:
		message = tr("Unknown Error!");
		break;
	}
	emit set_text(msg_widget_id, message);
	emit set_visible(msg_widget_id, true);

	m_prompt_timer->stop();
	m_prompt_timer->start(msg_period);
}

void UIWidgetController::set_prompt(QString msg)
{
	uint32_t msg_widget_id = (m_curr_scrn_id << 16) | SCRN_generic_TXT_prompt;
	uint32_t msg_period = PERIOD_SHORT;

	emit set_text(msg_widget_id, msg);
	emit set_visible(msg_widget_id, true);

	m_prompt_timer->stop();
	m_prompt_timer->start(msg_period);
}

void UIWidgetController::set_nc_fault_prompt(uint16_t error1, uint16_t error2)
{
	uint32_t msg_widget_id = (m_curr_scrn_id << 16) | SCRN_generic_TXT_prompt;
	uint32_t msg_period = PERIOD_LONG;
	QString msg;

	msg = tr("NoteCounter Fault, Please open the NoteCounter back-shell to clear!");
    msg += QString("%1 %2").arg(error1, 4, 16, QLatin1Char('0')).arg(error2, 4, 16, QLatin1Char('0'));
	emit set_text(msg_widget_id, msg);
	emit set_visible(msg_widget_id, true);

	m_prompt_timer->stop();
	m_prompt_timer->start(msg_period);

}

void UIWidgetController::prt_state_changed(bool online)
{
	emit set_btn_status((m_curr_scrn_id << 16) | BTN_printer_idx, online);
}

void UIWidgetController::notecounter_state_changed(bool online)
{
    emit set_btn_status((m_curr_scrn_id << 16) | BTN_notecounter_idx, online);
}

void UIWidgetController::server_state_changed(bool online)
{
	emit set_btn_status((m_curr_scrn_id << 16) | BTN_server_idx, online);
}

void UIWidgetController::bag_state_changed(bool closed)
{
	emit set_btn_status((m_curr_scrn_id << 16) | BTN_bag_idx, !closed);
}

void UIWidgetController::case_door_state_changed(bool closed)
{
	emit set_btn_status((m_curr_scrn_id << 16) | BTN_case_door_idx, closed);
}

void UIWidgetController::display_note(NoteInfo note_info)
{
	m_note_info = note_info;
	switch (m_curr_scrn_id) {
	case SCRN_intelligent_mode:
		for (int k = 0; k < NOTE_TYPE_COUNT; k++)
			if (note_info.note_count[k]) {
				emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(intelligent_mode, note_type), NOTE_name(k));
				emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(intelligent_mode, note_count), QString("%1").arg(note_info.note_count[k]));
				emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(intelligent_mode, note_total), QString("%1").arg(note_info.note_amount[k] / 100.0));
				break;
			}
		break;
	case SCRN_mixed_mode:
		emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(mixed_mode, note_count_100), QString("%1").arg(note_info.note_count[0]));
		emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(mixed_mode, note_total_100), QString("%1").arg(note_info.note_amount[0] / 100.0, 11, 'f', 2));
		emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(mixed_mode, note_count_50), QString("%1").arg(note_info.note_count[1]));
		emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(mixed_mode, note_total_50), QString("%1").arg(note_info.note_amount[1] / 100.0, 11, 'f', 2));
		emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(mixed_mode, note_count_20), QString("%1").arg(note_info.note_count[2]));
		emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(mixed_mode, note_total_20), QString("%1").arg(note_info.note_amount[2] / 100.0, 11, 'f', 2));
		emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(mixed_mode, note_count_10), QString("%1").arg(note_info.note_count[3]));
		emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(mixed_mode, note_total_10), QString("%1").arg(note_info.note_amount[3] / 100.0, 11, 'f', 2));
		emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(mixed_mode, note_count_5), QString("%1").arg(note_info.note_count[4]));
		emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(mixed_mode, note_total_5), QString("%1").arg(note_info.note_amount[4] / 100.0, 11, 'f', 2));
		emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(mixed_mode, note_count_1), QString("%1").arg(note_info.note_count[5]));
		emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(mixed_mode, note_total_1), QString("%1").arg(note_info.note_amount[5] / 100.0, 11, 'f', 2));
		emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(mixed_mode, note_count_total), QString("%1").arg(note_info.total_count));
		emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(mixed_mode, note_total_total), QString("%1").arg(note_info.total_amount / 100.0, 11, 'f', 2));
		break;
	case SCRN_count_mode:
		emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(count_mode, note_count), QString("%1").arg(note_info.total_count));
		break;
	case SCRN_deposit_note:
		emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(deposit_note, note_count_100), QString("%1").arg(note_info.note_count[0]));
		emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(deposit_note, note_total_100), QString("%1").arg(note_info.note_amount[0] / 100.0, 11, 'f', 2));
		emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(deposit_note, note_count_50), QString("%1").arg(note_info.note_count[1]));
		emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(deposit_note, note_total_50), QString("%1").arg(note_info.note_amount[1] / 100.0, 11, 'f', 2));
		emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(deposit_note, note_count_20), QString("%1").arg(note_info.note_count[2]));
		emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(deposit_note, note_total_20), QString("%1").arg(note_info.note_amount[2] / 100.0, 11, 'f', 2));
		emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(deposit_note, note_count_10), QString("%1").arg(note_info.note_count[3]));
		emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(deposit_note, note_total_10), QString("%1").arg(note_info.note_amount[3] / 100.0, 11, 'f', 2));
		emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(deposit_note, note_count_5), QString("%1").arg(note_info.note_count[4]));
		emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(deposit_note, note_total_5), QString("%1").arg(note_info.note_amount[4] / 100.0, 11, 'f', 2));
		emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(deposit_note, note_count_1), QString("%1").arg(note_info.note_count[5]));
		emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(deposit_note, note_total_1), QString("%1").arg(note_info.note_amount[5] / 100.0, 11, 'f', 2));
		emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(deposit_note, note_count_total), QString("%1").arg(note_info.total_count));
		emit set_text((m_curr_scrn_id << 16) | WIDGET_TXT(deposit_note, note_total_total), QString("%1").arg(note_info.total_amount / 100.0, 11, 'f', 2));
		break;
	}
}

void UIWidgetController::user_logged()
{
	switch (Coordinator::coordinator()->category_count()) {
	case 2:
	    emit set_screen(SCRN_deposit_category2);
        break;
	case 3:
	    emit set_screen(SCRN_deposit_category3);
	    break;
	case 4:
	    emit set_screen(SCRN_deposit_category4);
	    break;
	default:
	    emit set_screen(SCRN_deposit_category8);
		break;
	}
}

void UIWidgetController::admin_logged()
{
	emit set_screen(SCRN_administry);
}

void UIWidgetController::store_note_complete()
{
}

void UIWidgetController::store_coin_complete()
{
	qInfo() << "[UI]Complete Coin Store, Return to Deposit Class Screen";
//	emit pop_screen();
}

void UIWidgetController::data_show(QStringList s_list)
{
	emit set_screen(SCRN_deposit_table);
	emit set_table_data((SCRN_deposit_table << 16) | WIDGET_TAB(deposit_table, table), s_list);
}

void UIWidgetController::op_data_show(QStringList s_list)
{
	emit set_screen(SCRN_user_manage);
	emit set_table_data((SCRN_user_manage << 16) | WIDGET_TAB(user_manage, table), s_list);
}

void UIWidgetController::clr_data_show(QStringList s_list)
{
	emit set_screen(SCRN_clear_table);
	emit set_table_data((SCRN_clear_table << 16) | WIDGET_TAB(user_manage, table), s_list);
}

void UIWidgetController::clr_total_show(ClearInfo clr_info)
{
	emit set_screen(SCRN_clear_total);
	emit set_text((SCRN_clear_total << 16) | WIDGET_TXT(clear_total, note_total), QString("%1").arg(clr_info.note_amount / 100.0, 0, 'f', 2));
	emit set_text((SCRN_clear_total << 16) | WIDGET_TXT(clear_total, coin_total), QString("%1").arg(clr_info.coin_amount / 100.0, 0, 'f', 2));
	emit set_text((SCRN_clear_total << 16) | WIDGET_TXT(clear_total, total), QString("%1").arg(clr_info.amount / 100.0, 0, 'f', 2));
}

void UIWidgetController::do_edit_op(QString op_name, QString op_password, QString terminal_name, uint32_t op_finger_id)
{
	txt_changed((SCRN_user_edit << 16) | WIDGET_TXT(user_edit, user_name), op_name);
	txt_changed((SCRN_user_edit << 16) | WIDGET_TXT(user_edit, user_password), op_password);
	txt_changed((SCRN_user_edit << 16) | WIDGET_TXT(user_edit, station_id), terminal_name);
	txt_changed((SCRN_user_edit << 16) | WIDGET_TXT(user_edit, finger_id), QString("%1").arg(op_finger_id));

	emit set_visible((SCRN_user_edit << 16) | WIDGET_TXT(user_edit, finger_id), false);
	emit set_enable((SCRN_user_edit << 16) | WIDGET_TXT(user_edit, user_name), !m_user_edit);
	emit set_screen(SCRN_user_edit);
}

void UIWidgetController::count_starting()
{
    switch (m_curr_scrn_id) {
	case SCRN_count_mode:
		emit set_enable((SCRN_count_mode << 16) | WIDGET_BTN(count_mode, cancel), false);
		emit set_enable((SCRN_count_mode << 16) | WIDGET_BTN(count_mode, continue), false);
		break;
	case SCRN_mixed_mode:
		emit set_enable((SCRN_mixed_mode << 16) | WIDGET_BTN(mixed_mode, cancel), false);
		emit set_enable((SCRN_mixed_mode << 16) | WIDGET_BTN(mixed_mode, continue), false);
		break;
	case SCRN_intelligent_mode:
		emit set_enable((SCRN_intelligent_mode << 16) | WIDGET_BTN(intelligent_mode, cancel), false);
		emit set_enable((SCRN_intelligent_mode << 16) | WIDGET_BTN(intelligent_mode, continue), false);
		break;
    case SCRN_deposit_note:
		emit set_enable((SCRN_deposit_note << 16) | WIDGET_BTN(deposit_note, store), false);
		emit set_enable((SCRN_deposit_note << 16) | WIDGET_BTN(deposit_note, return), false);
		emit set_enable((SCRN_deposit_note << 16) | WIDGET_BTN(deposit_note, continue), false);
		break;
	}
}

void UIWidgetController::count_completing()
{
    switch (m_curr_scrn_id) {
	case SCRN_count_mode:
		emit set_enable((SCRN_count_mode << 16) | WIDGET_BTN(count_mode, cancel), true);
		emit set_enable((SCRN_count_mode << 16) | WIDGET_BTN(count_mode, continue), true);
		break;
	case SCRN_mixed_mode:
		emit set_enable((SCRN_mixed_mode << 16) | WIDGET_BTN(mixed_mode, cancel), true);
		emit set_enable((SCRN_mixed_mode << 16) | WIDGET_BTN(mixed_mode, continue), true);
		break;
	case SCRN_intelligent_mode:
		emit set_enable((SCRN_intelligent_mode << 16) | WIDGET_BTN(intelligent_mode, cancel), true);
		emit set_enable((SCRN_intelligent_mode << 16) | WIDGET_BTN(intelligent_mode, continue), true);
		break;
    case SCRN_deposit_note:
		emit set_enable((SCRN_deposit_note << 16) | WIDGET_BTN(deposit_note, store), true);
		emit set_enable((SCRN_deposit_note << 16) | WIDGET_BTN(deposit_note, return), true);
		emit set_enable((SCRN_deposit_note << 16) | WIDGET_BTN(deposit_note, continue), true);
		break;
	}
}

void UIWidgetController::store_starting()
{
    switch (m_curr_scrn_id) {
    case SCRN_deposit_note:
		emit set_enable((SCRN_deposit_note << 16) | WIDGET_BTN(deposit_note, store), false);
		emit set_enable((SCRN_deposit_note << 16) | WIDGET_BTN(deposit_note, return), false);
		emit set_enable((SCRN_deposit_note << 16) | WIDGET_BTN(deposit_note, continue), false);
		break;
    case SCRN_deposit_coin:
		emit set_enable((SCRN_deposit_coin << 16) | WIDGET_BTN(deposit_coin, store), false);
		emit set_enable((SCRN_deposit_coin << 16) | WIDGET_BTN(deposit_coin, return), false);
		break;
	}
}

void UIWidgetController::store_completing()
{
    switch (m_curr_scrn_id) {
    case SCRN_deposit_note:
		emit set_enable((SCRN_deposit_note << 16) | WIDGET_BTN(deposit_note, store), true);
		emit set_enable((SCRN_deposit_note << 16) | WIDGET_BTN(deposit_note, return), true);
		emit set_enable((SCRN_deposit_note << 16) | WIDGET_BTN(deposit_note, continue), true);
		break;
    case SCRN_deposit_coin:
		emit set_enable((SCRN_deposit_coin << 16) | WIDGET_BTN(deposit_coin, store), true);
		emit set_enable((SCRN_deposit_coin << 16) | WIDGET_BTN(deposit_coin, return), true);
		break;
	}
}

void UIWidgetController::set_user_name(QString name)
{
	m_user_name = name;

	for (int k = 0; k < m_screens.count(); k++) {
		Screen *screen = &m_screens[k];
		if (screen->scrn_id == SCRN_main) {
			for (int k = 0; k < screen->fields.count(); k++) {
				Field *field = &screen->fields[k];
				if (field->widget_id == WIDGET_TXT(main, username))
					field->widget_value = "";
//					field->widget_value = m_user_name;
			}
			break;
		}
	}
}

void UIWidgetController::set_machine_info(QString name, QString server_name, QString terminal_id)
{
	m_machine_name = name;
	m_http_server_name = server_name;
	m_terminal_id = terminal_id;
}

void UIWidgetController::fp_message(uint32_t proc, uint32_t enroll_step)
{
	QString prompt;

	switch (proc) {
	case FingerPrint_Worker::FP_PLACE_FINGER:
		prompt = tr("Place the finger") + QString("(%1)").arg(enroll_step + 1);
		break;
	case FingerPrint_Worker::FP_REMOVE_FINGER:
		prompt = tr("Remove the finger") + QString("(%1)").arg(enroll_step + 1);
		break;
	case FingerPrint_Worker::FP_CAPTURE_FINGER:
		prompt = tr("Capter the image") + QString("(%1)").arg(enroll_step + 1);
		break;
	case FingerPrint_Worker::FP_GENERATE_TEMPLATE:
		prompt = tr("Generate the template");
		break;
	case FingerPrint_Worker::FP_MERGE_TEMPLATE:
		prompt = tr("Merge the templates");
		break;
	case FingerPrint_Worker::FP_SAVE_TEMPLATE:
		prompt = tr("Save the merged template");
		break;
	case FingerPrint_Worker::FP_DUPLICATE_TEMPLATE:
		prompt = tr("Duplicated template!");
		break;
	default:
		prompt = "";
		break;
	}

	emit set_text((SCRN_user_edit << 16) | WIDGET_TXT(user_edit, prompt), prompt);
}

void UIWidgetController::scrn_widget_init()
{
	Field field;
	Screen screen;
	QDate date = QDate::currentDate();

	screen.scrn_id = SCRN_main;
	screen.fields.clear();
	field.widget_type = WIDGET_TYPE_TEXT;
	field.widget_id = WIDGET_TXT(main, username);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(main, password);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(main, software_version);
	field.widget_value = sw_version();
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(main, terminal_id);
	field.widget_value = Coordinator::coordinator()->get_terminal_id();
	screen.fields.append(field);
	m_screens.append(screen);

	screen.scrn_id = SCRN_password_modify;
	screen.fields.clear();
	field.widget_type = WIDGET_TYPE_TEXT;
	field.widget_id = WIDGET_TXT(password_modify, username);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(password_modify, old_password);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(password_modify, new_password);
	field.widget_value = "";
	screen.fields.append(field);
	m_screens.append(screen);

	screen.scrn_id = SCRN_intelligent_mode;
	screen.fields.clear();
	field.widget_type = WIDGET_TYPE_TEXT;
	field.widget_id = WIDGET_TXT(intelligent_mode, note_type);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(intelligent_mode, note_count);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(intelligent_mode, note_total);
	field.widget_value = "";
	screen.fields.append(field);
	m_screens.append(screen);

	screen.scrn_id = SCRN_mixed_mode;
	screen.fields.clear();
	field.widget_type = WIDGET_TYPE_TEXT;
	field.widget_id = WIDGET_TXT(mixed_mode, note_count_100);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(mixed_mode, note_total_100);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(mixed_mode, note_count_50);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(mixed_mode, note_total_50);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(mixed_mode, note_count_20);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(mixed_mode, note_total_20);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(mixed_mode, note_count_10);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(mixed_mode, note_total_10);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(mixed_mode, note_count_5);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(mixed_mode, note_total_5);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(mixed_mode, note_count_1);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(mixed_mode, note_total_1);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(mixed_mode, note_count_total);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(mixed_mode, note_total_total);
	field.widget_value = "";
	screen.fields.append(field);
	m_screens.append(screen);

	screen.scrn_id = SCRN_count_mode;
	screen.fields.clear();
	field.widget_type = WIDGET_TYPE_TEXT;
	field.widget_id = WIDGET_TXT(count_mode, note_count);
	field.widget_value = "";
	screen.fields.append(field);
	m_screens.append(screen);

	screen.scrn_id = SCRN_deposit_category8;
	screen.fields.clear();
	field.widget_type = WIDGET_TYPE_TEXT;
	field.widget_id = WIDGET_TXT(deposit_category8, category1);
	field.widget_value = Coordinator::coordinator()->category_description(0);
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_category8, category2);
	field.widget_value = Coordinator::coordinator()->category_description(1);
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_category8, category3);
	field.widget_value = Coordinator::coordinator()->category_description(2);
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_category8, category4);
	field.widget_value = Coordinator::coordinator()->category_description(3);
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_category8, category5);
	field.widget_value = Coordinator::coordinator()->category_description(0);
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_category8, category6);
	field.widget_value = Coordinator::coordinator()->category_description(1);
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_category8, category7);
	field.widget_value = Coordinator::coordinator()->category_description(2);
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_category8, category8);
	field.widget_value = Coordinator::coordinator()->category_description(3);
	screen.fields.append(field);
	m_screens.append(screen);

	screen.scrn_id = SCRN_deposit_category4;
	screen.fields.clear();
	field.widget_type = WIDGET_TYPE_TEXT;
	field.widget_id = WIDGET_TXT(deposit_category4, category1);
	field.widget_value = Coordinator::coordinator()->category_description(0);
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_category4, category2);
	field.widget_value = Coordinator::coordinator()->category_description(1);
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_category4, category3);
	field.widget_value = Coordinator::coordinator()->category_description(2);
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_category4, category4);
	field.widget_value = Coordinator::coordinator()->category_description(3);
	screen.fields.append(field);
	m_screens.append(screen);

	screen.scrn_id = SCRN_deposit_category3;
	screen.fields.clear();
	field.widget_type = WIDGET_TYPE_TEXT;
	field.widget_id = WIDGET_TXT(deposit_category3, category1);
	field.widget_value = Coordinator::coordinator()->category_description(0);
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_category3, category2);
	field.widget_value = Coordinator::coordinator()->category_description(1);
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_category3, category3);
	field.widget_value = Coordinator::coordinator()->category_description(2);
	screen.fields.append(field);
	m_screens.append(screen);

	screen.scrn_id = SCRN_deposit_category2;
	screen.fields.clear();
	field.widget_type = WIDGET_TYPE_TEXT;
	field.widget_id = WIDGET_TXT(deposit_category2, category1);
	field.widget_value = Coordinator::coordinator()->category_description(0);
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_category2, category2);
	field.widget_value = Coordinator::coordinator()->category_description(1);
	screen.fields.append(field);
	m_screens.append(screen);

	screen.scrn_id = SCRN_deposit_note;
	screen.fields.clear();
	field.widget_type = WIDGET_TYPE_TEXT;
	field.widget_id = WIDGET_TXT(deposit_note, note_count_100);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_note, note_total_100);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_note, note_count_50);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_note, note_total_50);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_note, note_count_20);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_note, note_total_20);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_note, note_count_10);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_note, note_total_10);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_note, note_count_5);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_note, note_total_5);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_note, note_count_1);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_note, note_total_1);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_note, note_count_total);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_note, note_total_total);
	field.widget_value = "";
	screen.fields.append(field);
	m_screens.append(screen);

	screen.scrn_id = SCRN_deposit_coin;
	screen.fields.clear();
	field.widget_type = WIDGET_TYPE_TEXT;
	field.widget_id = WIDGET_TXT(deposit_coin, note_count_100);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_coin, note_count_50);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_coin, note_count_20);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_coin, note_count_10);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_coin, note_count_5);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_coin, note_count_1);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_coin, note_count_05);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_coin, note_count_01);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_coin, note_count_001);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(deposit_coin, note_total);
	field.widget_value = "";
	screen.fields.append(field);
	m_screens.append(screen);

	screen.scrn_id = SCRN_deposit_inquiry;
	screen.fields.clear();
	field.widget_type = WIDGET_TYPE_SELECT;
	field.widget_id = WIDGET_SEL(deposit_inquiry, start_year);
	field.widget_value = QString("%1").arg(date.year() - 2024);
	screen.fields.append(field);
	field.widget_id = WIDGET_SEL(deposit_inquiry, start_month);
	field.widget_value = QString("%1").arg(date.month() - 1);
	screen.fields.append(field);
	field.widget_id = WIDGET_SEL(deposit_inquiry, start_day);
	field.widget_value = QString("%1").arg(date.day() - 1);
	screen.fields.append(field);
	field.widget_id = WIDGET_SEL(deposit_inquiry, stop_year);
	field.widget_value = QString("%1").arg(date.year() - 2024);
	screen.fields.append(field);
	field.widget_id = WIDGET_SEL(deposit_inquiry, stop_month);
	field.widget_value = QString("%1").arg(date.month() - 1);
	screen.fields.append(field);
	field.widget_id = WIDGET_SEL(deposit_inquiry, stop_day);
	field.widget_value = QString("%1").arg(date.day() - 1);
	screen.fields.append(field);
	m_screens.append(screen);

	screen.scrn_id = SCRN_deposit_table;
	screen.fields.clear();
	field.widget_type = WIDGET_TYPE_TABLE;
	field.widget_id = WIDGET_TAB(deposit_table, table);
	field.widget_value = "";
	screen.fields.append(field);
	m_screens.append(screen);

	screen.scrn_id = SCRN_user_manage;
	screen.fields.clear();
	field.widget_type = WIDGET_TYPE_TABLE;
	field.widget_id = WIDGET_TAB(user_manage, table);
	field.widget_value = "";
	screen.fields.append(field);
	m_screens.append(screen);

	screen.scrn_id = SCRN_machine_setting;
	screen.fields.clear();
	field.widget_type = WIDGET_TYPE_TEXT;
	field.widget_id = WIDGET_TXT(machine_setting, name);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(machine_setting, address);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(machine_setting, code);
	field.widget_value = "";
	screen.fields.append(field);
	m_screens.append(screen);

	screen.scrn_id = SCRN_clear_inquiry;
	screen.fields.clear();
	field.widget_type = WIDGET_TYPE_SELECT;
	field.widget_id = WIDGET_SEL(clear_inquiry, start_year);
	field.widget_value = QString("%1").arg(date.year() - 2024);
	screen.fields.append(field);
	field.widget_id = WIDGET_SEL(clear_inquiry, start_month);
	field.widget_value = QString("%1").arg(date.month() - 1);
	screen.fields.append(field);
	field.widget_id = WIDGET_SEL(clear_inquiry, start_day);
	field.widget_value = QString("%1").arg(date.day() - 1);
	screen.fields.append(field);
	field.widget_id = WIDGET_SEL(clear_inquiry, stop_year);
	field.widget_value = QString("%1").arg(date.year() - 2024);
	screen.fields.append(field);
	field.widget_id = WIDGET_SEL(clear_inquiry, stop_month);
	field.widget_value = QString("%1").arg(date.month() - 1);
	screen.fields.append(field);
	field.widget_id = WIDGET_SEL(clear_inquiry, stop_day);
	field.widget_value = QString("%1").arg(date.day() - 1);
	screen.fields.append(field);
	m_screens.append(screen);

	screen.scrn_id = SCRN_clear_total;
	screen.fields.clear();
	field.widget_type = WIDGET_TYPE_TEXT;
	field.widget_id = WIDGET_TXT(clear_total, note_total);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(clear_total, coin_total);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(clear_total, total);
	field.widget_value = "";
	screen.fields.append(field);
	m_screens.append(screen);

	screen.scrn_id = SCRN_user_edit;
	screen.fields.clear();
	field.widget_type = WIDGET_TYPE_TEXT;
	field.widget_id = WIDGET_TXT(user_edit, user_name);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(user_edit, user_password);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(user_edit, station_id);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(user_edit, prompt);
	field.widget_value = "";
	screen.fields.append(field);
	field.widget_id = WIDGET_TXT(user_edit, finger_id);
	field.widget_value = "";
	screen.fields.append(field);
	m_screens.append(screen);

}

void UIWidgetController::scrn_init(uint32_t scrn_id)
{
	Screen *screen;
	Field *field;

	m_curr_scrn_id = scrn_id;
	m_btn_locked = false;

	emit set_enable((scrn_id << 16) | SCRN_generic_ICO_bag, false);
	emit set_enable((scrn_id << 16) | SCRN_generic_ICO_server, false);
	emit set_enable((scrn_id << 16) | SCRN_generic_ICO_case_door, false);
	emit set_enable((scrn_id << 16) | SCRN_generic_ICO_printer, false);
	emit set_enable((scrn_id << 16) | SCRN_generic_ICO_network, false);
	emit set_visible((scrn_id << 16) | SCRN_generic_TXT_prompt, false);

	emit enter_screen(scrn_id);

	switch (scrn_id) {
	case SCRN_main:
		m_screen_stack.clear();
		for (int k = 0; k < m_screens.count(); k++) {
			screen = &m_screens[k];
			if (screen->scrn_id == scrn_id) {
				for (int k = 0; k < screen->fields.count(); k++) {
					field = &screen->fields[k];
					if (field->widget_id == WIDGET_TXT(main, password))
						field->widget_value = "";
				}
				break;
			}
		}
		break;
	case SCRN_deposit_inquiry:
		break;
	case SCRN_password_modify:
		for (int k = 0; k < m_screens.count(); k++) {
			screen = &m_screens[k];
			if (screen->scrn_id == scrn_id) {
				for (int k = 0; k < screen->fields.count(); k++) {
					field = &screen->fields[k];
					if (field->widget_type == WIDGET_TYPE_TEXT) {
						if (field->widget_id == WIDGET_TXT(password_modify, username)) {
							if (m_admin_status)
								field->widget_value = m_user_name;
							else
								field->widget_value = "";
						}
						else
							field->widget_value = "";
					}
				}
				break;
			}
		}
		break;
	case SCRN_intelligent_mode:
	case SCRN_mixed_mode:
	case SCRN_count_mode:
	case SCRN_deposit_note:
		memset(&m_note_info, 0, sizeof(m_note_info));
		for (int k = 0; k < m_screens.count(); k++) {
			screen = &m_screens[k];
			if (screen->scrn_id == scrn_id) {
				for (int k = 0; k < screen->fields.count(); k++) {
					field = &screen->fields[k];
					if (field->widget_type == WIDGET_TYPE_TEXT)
						field->widget_value = "0";
				}
				break;
			}
		}
		set_enable((SCRN_deposit_note << 16) | WIDGET_BTN(deposit_note, store), true);
		set_enable((SCRN_deposit_note << 16) | WIDGET_BTN(deposit_note, return), true);
		set_enable((SCRN_deposit_note << 16) | WIDGET_BTN(deposit_note, continue), true);
		break;
	case SCRN_deposit_coin:
		memset(&m_note_info, 0, sizeof(m_note_info));
		for (int k = 0; k < m_screens.count(); k++) {
			screen = &m_screens[k];
			if (screen->scrn_id == scrn_id) {
				for (int k = 0; k < screen->fields.count(); k++) {
					field = &screen->fields[k];
					if (field->widget_type == WIDGET_TYPE_TEXT)
						field->widget_value = "";
				}
				break;
			}
		}
		set_enable((SCRN_deposit_coin << 16) | WIDGET_BTN(deposit_coin, store), true);
		set_enable((SCRN_deposit_coin << 16) | WIDGET_BTN(deposit_coin, return), true);
		break;
	case SCRN_deposit_table:
		for (int k = 0; k < m_screens.count(); k++) {
			screen = &m_screens[k];
			if (screen->scrn_id == scrn_id) {
				for (int k = 0; k < screen->fields.count(); k++) {
					field = &screen->fields[k];
					if (field->widget_type == WIDGET_TYPE_TABLE)
						field->widget_value = "-1";
				}
				break;
			}
		}
		break;
	case SCRN_machine_setting:
		for (int k = 0; k < m_screens.count(); k++) {
			screen = &m_screens[k];
			if (screen->scrn_id == scrn_id) {
				for (int k = 0; k < screen->fields.count(); k++) {
					field = &screen->fields[k];
					switch (field->widget_id) {
					case WIDGET_TXT(machine_setting, name):
						field->widget_value = m_machine_name;
						break;
					case WIDGET_TXT(machine_setting, address):
						field->widget_value = m_http_server_name;
						break;
					case WIDGET_TXT(machine_setting, code):
                        field->widget_value = m_terminal_id;
						break;
					}
				}
				break;
			}
		}
		break;
	case SCRN_clear_table:
		for (int k = 0; k < m_screens.count(); k++) {
			screen = &m_screens[k];
			if (screen->scrn_id == scrn_id) {
				for (int k = 0; k < screen->fields.count(); k++) {
					field = &screen->fields[k];
					if (field->widget_type == WIDGET_TYPE_TABLE)
						field->widget_value = "-1";
				}
				break;
			}
		}
		break;
	case SCRN_user_edit:
		fp_message(-1, -1);
		break;
	case SCRN_store_fail:
		{
            uint32_t amount = Coordinator::coordinator()->get_last_subtrans().note_info.total_amount;
			QString s;
			if (Coordinator::coordinator()->get_account_failed_trans())
				s = QString(tr("Note/Coin saving process failed!\nThe last transaction(Amount: $%1.%2) was saved, Please contact the administrator!")).arg(amount / 100).arg(amount % 100, 2, 10, QLatin1Char('0'));
			else
				s = QString(tr("Note/Coin saving process failed!\nThe last transaction(Amount: $%1.%2) was not saved, Please contact the administrator!")).arg(amount / 100).arg(amount % 100, 2, 10, QLatin1Char('0'));
			emit set_text((SCRN_store_fail << 16) | SCRN_store_fail_TXT_info, s);
		}
		break;
	}
    if (m_screen_stack.isEmpty() || m_screen_stack.top() != scrn_id)
		m_screen_stack.push(scrn_id);

	foreach(auto screen, m_screens) {
		if (screen.scrn_id != scrn_id)
			continue;
		foreach(auto field, screen.fields) {
			if (field.widget_type == WIDGET_TYPE_TEXT)
				emit set_text((scrn_id << 16) | field.widget_id, field.widget_value);
			else if (field.widget_type == WIDGET_TYPE_SELECT)
				emit set_select((scrn_id << 16) | field.widget_id, field.widget_value.toUInt());
		}
	}
	emit set_text((scrn_id << 16) | TXT_username_idx, m_user_name);

	emit update_component_status();
}

void UIWidgetController::scrn_pop(uint32_t to_scrn_id)
{
	uint32_t last_scrn_id;

	if (!m_screen_stack.isEmpty())
		m_screen_stack.pop();
	while (!m_screen_stack.isEmpty()) {
		last_scrn_id = m_screen_stack.pop();
		if (to_scrn_id == 0xffffffff) {
			to_scrn_id = last_scrn_id;
			break;
		}
		else if (last_scrn_id == to_scrn_id)
			break;
	}

	if (to_scrn_id == 0xffffffff)
		to_scrn_id = SCRN_main;
	emit set_screen(to_scrn_id);
}

QString UIWidgetController::fetch_widget_value(uint32_t scrn_id, uint32_t widget_id)
{
	foreach(auto screen, m_screens) {
		if (screen.scrn_id != scrn_id)
			continue;
		foreach(auto field, screen.fields) {
			if (field.widget_id == widget_id)
				return field.widget_value;
		}
	}

	return "";
}
